<script setup lang="ts">
/**
 * 按钮权限管理模态框组件
 * @module PermissionDialog
 * @desc 用于角色按钮权限的分配管理
 */

import { ref, computed, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { queryMenuPermission, queryPermissionIdsWithRoleId, add } from '@/service/api/system-manage';
import { useBoolean } from '@sa/hooks';

// 组件配置
defineOptions({
  name: 'DhkPermissionDialog'
});

// 类型定义
interface Props {
  /** 是否可见 */
  visible: boolean;
  /** 角色ID */
  roleId: number;
}

// 组件props定义
const props = defineProps<Props>();

// 事件定义
const emit = defineEmits(['update:visible', 'close', 'success']);

// 加载和错误状态
const { bool: loading, setTrue: startLoading, setFalse: stopLoading } = useBoolean(false);
const { bool: fetchError, setTrue: setFetchError, setFalse: clearFetchError } = useBoolean(false);

// 响应式数据
const menuCategories = ref([]);
const checkedPermissionIds = ref([]);

// 对话框显示控制（计算属性）
const show = computed({
  get: () => props.visible,
  set: value => {
    emit('update:visible', value);
    if (!value) {
      emit('close');
    }
  }
});

// 当对话框显示或角色ID变化时加载数据
watch(() => props.visible, value => {
  if (value && props.roleId) {
    clearFetchError();
    refreshData();
  }
});

/**
 * 加载菜单权限数据
 * @function loadMenuPermissions
 * @desc 获取所有菜单及其按钮权限
 */
async function loadMenuPermissions() {
  loading.value = true;
  fetchError.value = false;

  try {
    const res = await queryMenuPermission();
    if (res?.data) {
      menuCategories.value = Array.isArray(res.data) ? res.data : [];
      console.log('菜单权限加载成功:', menuCategories.value.length, '个菜单');
    } else {
      console.error('菜单权限加载失败: 无数据');
      fetchError.value = true;
    }
  } catch (error) {
    console.error('菜单权限加载错误:', error);
    fetchError.value = true;
  } finally {
    loading.value = false;
  }
}

/**
 * 加载已选中的权限ID
 * @function loadCheckedPermissions
 * @desc 根据角色ID获取已授权的按钮权限ID
 */
async function loadCheckedPermissions() {
  if (!props.roleId) return;

  const roleId = Number(props.roleId);
  loading.value = true;

  try {
    const res = await queryPermissionIdsWithRoleId(roleId);
    checkedPermissionIds.value = Array.isArray(res?.data)
      ? res.data.map(id => Number(id)).filter(Boolean)
      : [];
    console.log('已选权限加载成功:', checkedPermissionIds.value.length, '个权限');
  } catch (error) {
    console.error('已选权限加载失败:', error);
    fetchError.value = true;
  } finally {
    loading.value = false;
  }
}

/**
 * 刷新所有数据
 * @function refreshData
 * @desc 重新加载菜单和权限数据
 */
function refreshData() {
  checkedPermissionIds.value = [];
  menuCategories.value = [];
  loadMenuPermissions();
  loadCheckedPermissions();
}

/**
 * 检查权限是否被选中
 * @function isChecked
 * @param {number} id - 权限ID
 * @returns {boolean} 是否选中
 */
function isChecked(id) {
  return checkedPermissionIds.value.includes(id);
}

/**
 * 切换权限选中状态
 * @function togglePermission
 * @param {number} id - 权限ID
 */
function togglePermission(id) {
  if (isChecked(id)) {
    checkedPermissionIds.value = checkedPermissionIds.value.filter(i => i !== id);
  } else {
    checkedPermissionIds.value.push(id);
  }
}

/**
 * 关闭对话框
 * @function closeDialog
 */
function closeDialog() {
  emit('update:visible', false);
  emit('close');
}

/**
 * 提交权限配置
 * @function handleSubmit
 * @desc 提交选中的权限ID到后端保存
 */
async function handleSubmit() {
  if (!props.roleId) {
    ElMessage.warning('请选择角色');
    return;
  }

  loading.value = true;
  
  try {
    const params = {
      roleId: Number(props.roleId),
      permissionIds: checkedPermissionIds.value
    };

    await add(params);
    ElMessage.success('权限更新成功');
    emit('success');
    closeDialog();
  } catch (error) {
    console.error('提交权限配置失败:', error);
    ElMessage.error('提交失败');
  } finally {
    loading.value = false;
  }
}
</script>

<template>
  <!-- 按钮权限配置对话框 -->
  <ElDialog
    v-model="show"
    title="编辑按钮权限"
    width="800px"
    destroy-on-close
    :close-on-click-modal="false"
    @closed="closeDialog"
  >
    <!-- 内容区域 -->
    <div v-loading="loading" class="permission-container">
      <!-- 错误提示 -->
      <div v-if="fetchError" class="flex-center h-full">
        <div class="text-center">
          <div class="text-red-500 text-xl mb-4">操作失败</div>
          <div class="mb-4">获取权限数据失败，请刷新重试</div>
          <ElButton type="primary" @click="refreshData">重新加载</ElButton>
        </div>
      </div>

      <!-- 权限表格 -->
      <div v-else>
        <div class="category-section">
          <!-- 表头 -->
          <div class="category-header">
            <div class="menu-column">菜单分类</div>
            <div class="permissions-column">可用权限</div>
            <div class="operation-column">删除</div>
          </div>
          
          <!-- 父菜单行 -->
          <div v-for="menu in menuCategories" :key="menu.menuId" class="category-row">
            <div class="menu-column parent-menu">{{ menu.menuName || '未命名菜单' }}</div>
            <div class="permissions-column">
              <ElCheckbox 
                v-for="button in menu.buttons || []" 
                :key="button.id"
                :model-value="isChecked(button.id)"
                @change="() => togglePermission(button.id)"
                class="permission-checkbox"
              >
                {{ button.description || button.name }}
              </ElCheckbox>
            </div>
            <div class="operation-column">
              <span class="delete-text">删除</span>
            </div>
          </div>
          
          <!-- 子菜单行 -->
          <template v-for="parent in menuCategories" :key="parent.menuId + '-children'">
            <div v-for="child in parent.children || []" :key="child.menuId" class="category-row child-row">
              <div class="menu-column child-menu">{{ child.menuName || '未命名子菜单' }}</div>
              <div class="permissions-column">
                <ElCheckbox 
                  v-for="button in child.buttons || []" 
                  :key="button.id"
                  :model-value="isChecked(button.id)"
                  @change="() => togglePermission(button.id)"
                  class="permission-checkbox"
                >
                  {{ button.description || button.name }}
                </ElCheckbox>
                
                <span v-if="(child.buttons || []).length === 0" class="no-permissions">
                  该菜单暂无可配置权限
                </span>
              </div>
              <div class="operation-column">
                <span class="delete-text">删除</span>
              </div>
            </div>
          </template>
        </div>
      </div>
    </div>

    <!-- 底部按钮 -->
    <template #footer>
      <div class="flex justify-end">
        <ElButton @click="closeDialog">取消</ElButton>
        <ElButton type="primary" :loading="loading" @click="handleSubmit">
          确认
        </ElButton>
      </div>
    </template>
  </ElDialog>
</template>

<style scoped>
/* 权限容器样式 */
.permission-container {
  height: 600px;
  overflow: auto;
}

/* 分类区域样式 */
.category-section {
  display: flex;
  flex-direction: column;
  width: 100%;
}

/* 表头样式 */
.category-header {
  display: flex;
  background-color: #f5f7fa;
  font-weight: bold;
  border-bottom: 1px solid #dcdfe6;
}

/* 菜单列样式 */
.menu-column {
  width: 200px;
  padding: 12px 15px;
  border-right: 1px solid #dcdfe6;
}

/* 权限列样式 */
.permissions-column {
  flex: 1;
  padding: 12px 15px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  border-right: 1px solid #dcdfe6;
}

/* 操作列样式 */
.operation-column {
  width: 80px;
  padding: 12px 15px;
  text-align: center;
}

.delete-text {
  color: #f56c6c;
  font-weight: bold;
}

/* 行样式 */
.category-row {
  display: flex;
  border-bottom: 1px solid #ebeef5;
}

.category-row:hover {
  background-color: #f5f7fa;
}

/* 父菜单样式 */
.parent-menu {
  font-weight: bold;
  background-color: #f0f2f5;
}

/* 子菜单行样式 */
.child-row {
  background-color: #fafafa;
}

/* 子菜单样式 */
.child-menu {
  padding-left: 30px;
}

/* 权限复选框样式 */
.permission-checkbox {
  margin-right: 15px;
  margin-bottom: 5px;
}

/* 无权限提示样式 */
.no-permissions {
  color: #909399;
  font-style: italic;
}

/* 通用样式 */
.flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

.h-full {
  height: 100%;
}

.flex {
  display: flex;
}

.justify-end {
  justify-content: flex-end;
}

.text-center {
  text-align: center;
}

.text-red-500 {
  color: #f56c6c;
}

.text-xl {
  font-size: 1.25rem;
}

.mb-4 {
  margin-bottom: 1rem;
}
</style> 